package dev.tools;

import com.sun.tools.attach.VirtualMachine;
import dev.tools.constant.Constants;
import dev.tools.exchange.Client;
import dev.tools.exchange.Server;
import dev.tools.utils.AppUtils;
import io.netty.util.internal.StringUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;

public class DevToolsBootstrap {

    private static Client client = new Client(Constants.SERVER_LISTENER_PORT);

    private static String fileUrl;

    private static String savePath = "/tmp/core.jar";

    private static Properties properties = new Properties();

    private static Server server = new Server(Constants.SERVER_LISTENER_PORT);

    static {
        try {
//            ClassPathUtils.addFile(System.getProperty("java.home") + "/../lib/tools.jar");
            properties.load(DevToolsBootstrap.class.getResourceAsStream("/bootstrap.properties"));
        } catch (IOException e) {
        }
    }

    public static void main(String[] args) {
        if (args != null && args.length > 0) {
            attach(args[0]);
        }
    }

    public static void attach(String pid) {

        VirtualMachine virtualMachine = null;

        try {
            try {
                InputStream in = DevToolsBootstrap.class.getResourceAsStream("/core.jar");
                AppUtils.copyStreamToFile(in, savePath);
            } catch (Exception e) {
                fileUrl = properties.getProperty("remote.jar.url");
                String shell = String.format("/usr/bin/env test -f %s || /usr/bin/env wget -O %s %s", savePath, savePath, fileUrl);

                Runtime.getRuntime()
                        .exec(new String[]{"/bin/sh", "-c", shell})
                        .waitFor();
            }
            virtualMachine = VirtualMachine.attach(StringUtil.isNullOrEmpty(pid) ? AppUtils.getPid() : pid);
            virtualMachine.loadAgent(savePath, "");
            server.startHttpServer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != virtualMachine) {
                try {
                    virtualMachine.detach();
                } catch (Exception e) {
                }
            }
        }
    }

    public static String render(String submitNewCodeUrl) throws Exception {
        try (InputStream inputStream = DevToolsBootstrap.class.getResourceAsStream("/form.html");
             BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
        ) {
            StringBuilder html = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                html.append(line);
            }
            return html.toString().replace("${SubmitNewCodeUrl}", submitNewCodeUrl);
        } catch (Exception e) {
            throw e;
        }
    }

    public static String distCode(List<String> hosts, String code) throws Exception {
        StringBuilder res = new StringBuilder();
        if (hosts == null || hosts.size() == 0) {
            return "";
        }
        for (String host : hosts) {
            res.append(host).append(":");
            try {
                res.append(client.send(host, code));
            } catch (Exception e) {
                res.append(e.getMessage());
                e.printStackTrace();
            }
            res.append(";");
        }
        return res.toString();

    }
}
